package com.ruoyi.tb.lmt.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.tb.lmt.domain.Constant;
import com.ruoyi.tb.lmt.domain.TbLocomotive;
import com.ruoyi.tb.lmt.domain.TbRepairplanlist;
import com.ruoyi.tb.lmt.domain.vo.LmtNumberVo;
import com.ruoyi.tb.lmt.domain.vo.TbLocomotiveVo;
import com.ruoyi.tb.lmt.domain.vo.TbRepairplanlistVo;
import com.ruoyi.tb.lmt.mapper.TbLocomotiveMapper;
import com.ruoyi.tb.lmt.mapper.TbRepairplanlistMapper;
import lombok.RequiredArgsConstructor;
import org.hibernate.validator.internal.util.StringHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import com.ruoyi.tb.lmt.domain.bo.TbParkingBo;
import com.ruoyi.tb.lmt.domain.vo.TbParkingVo;
import com.ruoyi.tb.lmt.domain.TbParking;
import com.ruoyi.tb.lmt.mapper.TbParkingMapper;
import com.ruoyi.tb.lmt.service.ITbParkingService;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 存车场信息Service业务层处理
 *
 * @author ruoyi
 * @date 2024-01-23
 */
@RequiredArgsConstructor
@Service
public class TbParkingServiceImpl implements ITbParkingService {

    private final TbParkingMapper baseMapper;

    @Autowired
    private TbRepairplanlistMapper tbRepairplanlistMapper;

    @Autowired
    private TbLocomotiveMapper tbLocomotiveMapper;

    @Autowired
    private TbParkingMapper tbParkingMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final List<Map<String, String>> FIXED_OUT_IP_LIST;

    //todo：设置固定出车IP
    static {
        List<Map<String, String>> list = new ArrayList<>();
        Map<String, String> map1 = new HashMap<>();
        map1.put("trackName", "9股");
        map1.put("fromIp", "004");
        list.add(map1);

        Map<String, String> map2 = new HashMap<>();
        map2.put("trackName", "8股");
        map2.put("fromIp", "005");
        list.add(map2);

        FIXED_OUT_IP_LIST = Collections.unmodifiableList(list);
    }

    /**
     * 查询存车场信息
     */
    @Override
    public TbParkingVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询存车场信息列表
     */
    @Override
    public TableDataInfo<TbParkingVo> queryPageList(TbParkingBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TbParking> lqw = buildQueryWrapper(bo);
        Page<TbParkingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        java.util.Date date = DateUtils.getNowDate();
        for (TbParkingVo vo : result.getRecords()) {
            if (StringUtils.isNotBlank(vo.getLmtNumber())) {
                TbLocomotiveVo tbLocomotiveVo = tbLocomotiveMapper.selectLocomotive(vo.getLmtNumber());
                if (tbLocomotiveVo != null) {
                    vo.setWorkGroup(tbLocomotiveVo.getWorkGroup());
                }
                if (vo.getEnterTime() != null) {
                    vo.setDay(DateUtils.differentDaysByMillisecond(vo.getEnterTime(), date));
                }
            }
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询存车场信息列表
     */
    @Override
    public List<TbParkingVo> queryList(TbParkingBo bo) {
        LambdaQueryWrapper<TbParking> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TbParking> buildQueryWrapper(TbParkingBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TbParking> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getTrackId() != null, TbParking::getTrackId, bo.getTrackId());
        lqw.eq(bo.getRequireId() != null, TbParking::getRequireId, bo.getRequireId());
        lqw.like(StringUtils.isNotBlank(bo.getLmtType()), TbParking::getLmtType, bo.getLmtType());
        lqw.like(StringUtils.isNotBlank(bo.getLmtNumber()), TbParking::getLmtNumber, bo.getLmtNumber());
        lqw.eq(bo.getLmtRepairId() != null, TbParking::getLmtRepairId, bo.getLmtRepairId());
        lqw.eq(StringUtils.isNotBlank(bo.getRepairType()), TbParking::getRepairType, bo.getRepairType());
        lqw.like(StringUtils.isNotBlank(bo.getPlanName()), TbParking::getPlanName, bo.getPlanName());
        lqw.eq(StringUtils.isNotBlank(bo.getPlanStatus()), TbParking::getPlanStatus, bo.getPlanStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getWorkGroup()), TbParking::getWorkGroup, bo.getWorkGroup());
        lqw.eq(bo.getWorkGroupId() != null, TbParking::getWorkGroupId, bo.getWorkGroupId());
        lqw.like(StringUtils.isNotBlank(bo.getTrackName()), TbParking::getTrackName, bo.getTrackName());
        lqw.like(StringUtils.isNotBlank(bo.getDrivewayName()), TbParking::getDrivewayName, bo.getDrivewayName());
        lqw.eq(bo.getEnterTime() != null, TbParking::getEnterTime, bo.getEnterTime());
        lqw.eq(bo.getCreateTime() != null, TbParking::getCreateTime, bo.getCreateTime());
        lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), TbParking::getCreateBy, bo.getCreateBy());
        lqw.eq(bo.getUpdateTime() != null, TbParking::getUpdateTime, bo.getUpdateTime());
        lqw.eq(StringUtils.isNotBlank(bo.getUpdateBy()), TbParking::getUpdateBy, bo.getUpdateBy());
        lqw.eq(StringUtils.isNotBlank(bo.getParkingNeed()), TbParking::getParkingNeed, bo.getParkingNeed());
        lqw.eq(StringUtils.isNotBlank(bo.getParkingNeed2()), TbParking::getParkingNeed2, bo.getParkingNeed2());
        return lqw;
    }

    /**
     * 新增存车场信息
     */
    @Override
    public Boolean insertByBo(TbParkingBo bo) {
        TbParking add = BeanUtil.toBean(bo, TbParking.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改存车场信息
     */
    @Override
    public Boolean updateByBo(TbParkingBo bo) {
        TbParking update = BeanUtil.toBean(bo, TbParking.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TbParking entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除存车场信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public TbParkingBo updateParking(TbParkingBo bo) {
        if ((bo.getLmtType() != null && !bo.getLmtType().isEmpty()) && (bo.getLmtNumber() != null && !bo.getLmtNumber().isEmpty())) {
            Long lmtRepairId = tbRepairplanlistMapper.selectLmtId(bo.getLmtType(), bo.getLmtNumber());
            bo.setLmtRepairId(lmtRepairId);
            TbRepairplanlist planList = tbRepairplanlistMapper.selectPlanById(lmtRepairId);
            if (planList != null) {
                if (planList.getPlanName() != null) {
                    bo.setPlanName(planList.getPlanName());
                }
                if (planList.getStatus() != null) {
                    bo.setPlanStatus(planList.getStatus());
                }
                if (planList.getRepairType() != null) {
                    bo.setRepairType(planList.getRepairType());
                }
                if (planList.getWorkGroup() != null) {
                    bo.setWorkGroup(planList.getWorkGroup());
                }
                if (planList.getWorkGroupId() != null) {
                    bo.setWorkGroupId(planList.getWorkGroupId());
                }
            }
            return bo;
        } else {
            bo.setLmtRepairId(null);
            bo.setPlanName("");
            bo.setPlanStatus("");
            bo.setRepairType("");
            bo.setWorkGroup("");
            bo.setParkingNeed("");
            bo.setWorkGroupId(null);
            return bo;
        }
    }


    @Override
    public Boolean updateByIp(String fromIp, String rfidBzm) {

        // 通过 rfidBzm 获取车号
        TbLocomotiveVo tbLocomotiveVo1 = tbLocomotiveMapper.selectLocomotiveByrfidBzm(rfidBzm);
        if (tbLocomotiveVo1 == null) {
            // 没有找到对应的车辆，可以根据业务需求抛出异常或进行其他处理
            return false;
//            throw new IllegalStateException("No locomotive found for RFID: " + rfidBzm);
        }

        // 获取车辆的车号
        String lmtNumber = tbLocomotiveVo1.getLmtNumber();

        // 判断传入的fromIp是否为固定出去的IP
        if (isFixedOutIp(fromIp)) {
            // 根据 trackName 查找所有位置，并删除车号
            handleFixedOutIpLogic(lmtNumber, fromIp);
        } else {
            // 执行进出逻辑
            handleEntryExitLogic(lmtNumber, fromIp);
        }
        return true;
    }

    private boolean isFixedOutIp(String fromIp) {
        return FIXED_OUT_IP_LIST.stream().anyMatch(ipMap -> ipMap.get("fromIp").equals(fromIp));
    }

    private void handleFixedOutIpLogic(String lmtNumber, String fromIp) {
        // 根据 fromIp 查找对应的 trackName
        String trackName = FIXED_OUT_IP_LIST.stream()
            .filter(ipMap -> ipMap.get("fromIp").equals(fromIp))
            .findFirst()
            .orElseThrow(() -> new IllegalStateException("Invalid fixed out IP: " + fromIp))
            .get("trackName");

        // 根据 trackName 查找所有位置
        List<TbParkingVo> parkings = tbParkingMapper.selectParkingByTrackName(trackName);

        // 查看所有位置下，存不存在车号，如果存在就删除
        parkings.stream()
            .filter(parking -> lmtNumber.equals(parking.getLmtNumber()))
            .findFirst()
            .ifPresent(parking -> {
                // 删除操作
                Long id = parking.getId();
                TbParking bo = new TbParking();
                bo.setId(id);
                bo.setLmtNumber(null);
                bo.setLmtRepairId(null);
                bo.setPlanName("");
                bo.setPlanStatus("");
                bo.setRepairType("");
                bo.setWorkGroup("");
                bo.setWorkGroupId(null);
                baseMapper.updateById(bo);

            });
    }

    private void handleEntryExitLogic(String lmtNumber, String fromIp) {
        // 通过 fromIp 获取这个IP感应器下控制的轨道位置和数量集合
        List<TbParkingVo> tbParkingList = tbParkingMapper.selectParkingList(fromIp);

        // 查找当前fromIp控制区域的车位中是否存在该车号
        Optional<TbParkingVo> existingParkingOpt = tbParkingList.stream()
            .filter(parking -> lmtNumber.equals(parking.getLmtNumber()))
            .findFirst();

        //找到轨道数
        String trackName = tbParkingList.isEmpty() ? null : tbParkingList.get(0).getTrackName();
        // 无论车辆是否存在，都进行查找和潜在的删除操作
        // 找出所有这个轨道上的车位
        List<TbParkingVo> allTrackParkings = tbParkingMapper.selectParkingByTrackName(trackName);

        // 找到与当前车号相同且fromIp不同的车位，这将是我们需要删除的车位
        Optional<TbParkingVo> toBeRemovedParkingOpt = allTrackParkings.stream()
            .filter(parking -> lmtNumber.equals(parking.getLmtNumber()) && !fromIp.equals(parking.getFromIp()))
            .findFirst();

        // 如果找到了，删除该车位上的车号
        toBeRemovedParkingOpt.ifPresent(this::removeLmtNumberFromParking);

        // 如果当前控制区域存在车辆，更新它的位置
        if (existingParkingOpt.isPresent()) {
            TbParkingVo existingParking = existingParkingOpt.get();
            removeLmtNumberFromParking(existingParking);

            // 找到比存在车号 drivewayName 值小但离 drivewayName 最近的 fromIp，但fromIp不同的fromIp
            String closestFromIp = findClosestSmallerDistinctFromIp(allTrackParkings, existingParking.getDrivewayName(), fromIp);

            // 如果找到，更新这个新fromIp控制下的集合中的车号
            if (closestFromIp != null) {
                List<TbParkingVo> newTbParkingList = tbParkingMapper.selectParkingList(closestFromIp);
                TbParkingVo middleParking = findMiddleParking(newTbParkingList);
                if (middleParking != null) {
                    insertLmtNumberToParking(middleParking, lmtNumber);
                }
            }
        } else {
            // 如果当前控制区域不存在车辆，尝试添加它
            // 因为添加新车辆前我们已经执行了删除操作，所以这里不需要再次删除
            TbParkingVo middleParking = findMiddleParking(tbParkingList);
            if (middleParking != null) {
                insertLmtNumberToParking(middleParking, lmtNumber);
            }
        }
    }

    private void removeLmtNumberFromParking(TbParkingVo parking) {
        Long id = parking.getId();
        TbParking bo = new TbParking();
        bo.setId(id);
        bo.setLmtNumber(null);
        bo.setLmtType(null);
        bo.setLmtRepairId(null);
        bo.setPlanName("");
        bo.setPlanStatus("");
        bo.setRepairType("");
        bo.setWorkGroup("");
        bo.setWorkGroupId(null);
        baseMapper.updateById(bo);
    }

    private void insertLmtNumberToParking(TbParkingVo parking, String lmtNumber) {
        Long id = parking.getId();
        TbParking bo = new TbParking();
        bo.setId(id);
        bo.setLmtNumber(lmtNumber);
        bo.setLmtType(tbLocomotiveMapper.selectLmtTypeByLmtNumber(lmtNumber));
        if (bo.getLmtType() != null || bo.getLmtNumber() != null) {
            Long lmtRepairId = tbRepairplanlistMapper.selectLmtId(bo.getLmtType(), bo.getLmtNumber());
            bo.setLmtRepairId(lmtRepairId);
            TbRepairplanlist planList = tbRepairplanlistMapper.selectPlanById(lmtRepairId);
            if (planList != null) {
                if (planList.getPlanName() != null) {
                    bo.setPlanName(planList.getPlanName());
                }
                if (planList.getStatus() != null) {
                    bo.setPlanStatus(planList.getStatus());
                }
                if (planList.getRepairType() != null) {
                    bo.setRepairType(planList.getRepairType());
                }
                if (planList.getWorkGroup() != null) {
                    bo.setWorkGroup(planList.getWorkGroup());
                }
                if (planList.getWorkGroupId() != null) {
                    bo.setWorkGroupId(planList.getWorkGroupId());
                }
            }
            baseMapper.updateById(bo);
        }
    }

    // 完成中间值车位的查找
    private TbParkingVo findMiddleParking(List<TbParkingVo> tbParkingList) {
        if (tbParkingList == null || tbParkingList.isEmpty()) {
            return null; // 空列表或null则返回null
        }

        // 过滤掉已经有车号的车位
        List<TbParkingVo> availableParkings = tbParkingList.stream()
            .filter(parking -> parking.getLmtNumber() == null || parking.getLmtNumber().isEmpty())
            .collect(Collectors.toList());

        if (availableParkings.isEmpty()) {
            return null; // 如果没有可用的车位，则返回null
        }

        // 先按drivewayName排序
        availableParkings.sort(Comparator.comparingInt(p -> Integer.parseInt(p.getDrivewayName())));

        // 然后找到中间索引的车位
        int middleIndex = availableParkings.size() / 2;
        if (availableParkings.size() % 2 == 0) {
            middleIndex--; // 如果是偶数，取左中位数
        }

        // 返回中间索引对应的对象
        return availableParkings.get(middleIndex);
    }

    private String findClosestSmallerDistinctFromIp(List<TbParkingVo> tbParkingList, String targetDrivewayName, String currentFromIp) {
        int targetValue;
        try {
            targetValue = Integer.parseInt(targetDrivewayName);
        } catch (NumberFormatException e) {
            // 如果targetDrivewayName不是整数，返回null或者抛出异常
            return null;
        }

        // 过滤出所有drivewayName比给定值小的TbParkingVo对象，排除fromIp相同的，并按drivewayName排序
        List<TbParkingVo> eligibleParkingSpots = tbParkingList.stream()
            .filter(p -> {
                try {
                    return p.getDrivewayName() != null
                        && Integer.parseInt(p.getDrivewayName()) < targetValue
                        && !p.getFromIp().equals(currentFromIp);
                } catch (NumberFormatException e) {
                    // 如果drivewayName无法解析成整数，忽略这个元素
                    return false;
                }
            })
            .sorted(Comparator.comparingInt(p -> -Integer.parseInt(p.getDrivewayName()))) // 注意这里是降序排序
            .collect(Collectors.toList());

        // 如果没有找到合适的车位，返回null
        if (eligibleParkingSpots.isEmpty()) {
            return null;
        }

        // 取出列表中第一个元素，即drivewayName最接近且小于目标值的对象
        TbParkingVo closestSmaller = eligibleParkingSpots.get(0);

        // 返回对应的fromIp
        return closestSmaller.getFromIp();
    }

    @Override
    public Boolean handleUpdateRequest(Date date, String fromIp, String rfidBzm) {

        // 生成一个用于Redis的key
        String redisKey = "updateRequest:" + fromIp + ":" + rfidBzm;

        // 获取Redis中的值操作对象
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();

        // 从Redis获取上一次请求的时间戳
        String lastRequestDateStr = valueOperations.get(redisKey);
        Date lastRequestDate = null;
        if (lastRequestDateStr != null) {
            // 将时间戳转换回Date
            lastRequestDate = new Date(Long.parseLong(lastRequestDateStr));
        }

        // 检查时间差
        if (lastRequestDate != null) {
            // 如果上一次请求在两分钟之内，更新Redis中的时间戳但不执行updateByIp
            System.out.println("两分钟内");
            valueOperations.set(redisKey, String.valueOf(date.getTime()), 10, TimeUnit.SECONDS);
            return false;
        } else {
            // 如果没有记录或时间差超出两分钟，执行updateByIp并在Redis中记录当前请求时间
            System.out.println("更新车位");
            Boolean result = updateByIp(fromIp, rfidBzm);
            valueOperations.set(redisKey, String.valueOf(date.getTime()));
            return result;
        }
    }

    @Override
    public List<TbParkingVo> queryList1(TbParkingBo bo) {
        LambdaQueryWrapper<TbParking> lqw = buildQueryWrapper(bo);
//        lqw.ne(TbParking::getPlanStatus, "已完成");
        lqw.isNotNull(TbParking::getLmtNumber);
        lqw.ne(TbParking::getLmtNumber, "");
        List<TbParkingVo> tbParkingVos = baseMapper.selectVoList(lqw);
        for (TbParkingVo tbParkingVo : tbParkingVos) {
            if (tbParkingVo.getLmtRepairId() != null) {
                TbRepairplanlist planList = tbRepairplanlistMapper.selectPlanById(tbParkingVo.getLmtRepairId());
                if (planList != null && StringUtils.isNotBlank(planList.getStatus())
                    && !planList.getStatus().equals(tbParkingVo.getPlanStatus())) {
                    tbParkingVo.setPlanStatus(planList.getStatus());
                    TbParkingBo bo1 = new TbParkingBo();
                    bo1.setId(tbParkingVo.getId());
                    bo1.setPlanStatus(tbParkingVo.getPlanStatus());
                    updateParking(bo1);
                }
            }
        }
        return tbParkingVos;
    }

    @Override
    public int countByDay(LocalDate recentDay) {
        return baseMapper.countByKey(recentDay);
    }

    /**
     * 根据传感器更新车位信息
     *
     * @param date
     * @param fromIp
     * @param rfidBzm
     * @return
     */
    @Override
    public String handleUpdateRequest1(Date date, String fromIp, String rfidBzm) {
        //根据rfidBzm查询大机配属
        TbLocomotiveVo tbLocomotiveVo = tbLocomotiveMapper.selectLocomotiveByrfidBzm(rfidBzm);
        if (tbLocomotiveVo == null) {
            return "大机不存在";
        }
        String key = Constant.FID + tbLocomotiveVo.getLmtNumber() + ":" + fromIp;
        ValueOperations<String, String> redis = stringRedisTemplate.opsForValue();
        String redisStr = redis.get(key);
        String str = "";
        if (StringUtils.isBlank(redisStr)) {
            if (rfidBzm.equals(tbLocomotiveVo.getRfidBzmQ())) {
                //头先进去
                redis.set(key, tbLocomotiveVo.getRfidBzmH(), 2, TimeUnit.MINUTES);
            } else if (rfidBzm.equals(tbLocomotiveVo.getRfidBzmH())) {
                //屁股先进
                redis.set(key, tbLocomotiveVo.getRfidBzmQ(), 2, TimeUnit.MINUTES);
            }
            return "";
        } else {
            if (redisStr.equals(tbLocomotiveVo.getRfidBzmH())) {
                //头先进去
                str = "0";
            } else if ( redisStr.equals(tbLocomotiveVo.getRfidBzmQ())) {
                //尾先进去
                str = "1";
            }else {
                if (rfidBzm.equals(tbLocomotiveVo.getRfidBzmQ())) {
                    //头先进去
                    redis.set(key, tbLocomotiveVo.getRfidBzmH(), 2, TimeUnit.MINUTES);
                } else if (rfidBzm.equals(tbLocomotiveVo.getRfidBzmH())) {
                    //屁股先进
                    redis.set(key, tbLocomotiveVo.getRfidBzmQ(), 2, TimeUnit.MINUTES);
                }
                return "";
            }
        }
        List<TbParkingVo> tbParkingVos = tbParkingMapper.selectParkingList(fromIp);
        if (tbParkingVos == null || tbParkingVos.size() == 0) {
            return "fip不存在。";
        }
        //车位
        TbParkingVo tbParkingVo = tbParkingVos.get(0);
        setDrivewayNames();
        if ("1".equals(tbParkingVo.getDrivewayName())) {
            //头先进去
            if (str.equals("0")) {
                //出库
                TbParkingVo tbParkingVo1 = tbParkingMapper.selectByLmtNumber(tbLocomotiveVo.getLmtNumber());
                if (tbParkingVo1 != null) {
                    TbParkingBo bo = new TbParkingBo();
                    bo.setId(tbParkingVo1.getId());
                    bo.setLmtNumber("");
                    bo.setLmtType("");
                    bo.setParkingNeed("");
                    TbParkingBo bo1 = updateParking(bo);
                    updateByBo(bo1);
                }
            } else {
                //入库
                change(j1, String.valueOf(tbParkingVo.getTrackId()), false, tbLocomotiveVo);
            }
        } else if ("4".equals(tbParkingVo.getDrivewayName()) || "5".equals(tbParkingVo.getDrivewayName())) {
            if (str.equals("0")) {
                change(j1, String.valueOf(tbParkingVo.getTrackId()), true, tbLocomotiveVo);
            } else {
                change(j2, String.valueOf(tbParkingVo.getTrackId()), false, tbLocomotiveVo);
            }
        } else if ("8".equals(tbParkingVo.getDrivewayName())) {
            if (str.equals("0")) {
                change(j2, String.valueOf(tbParkingVo.getTrackId()), true, tbLocomotiveVo);
            } else {
                List<String> j3 = tbParkingMapper.selectJ3(tbParkingVo.getTrackId());
                change(j3, String.valueOf(tbParkingVo.getTrackId()), false, tbLocomotiveVo);
            }
        } else {
            return "失败";
        }
        stringRedisTemplate.delete(key);
        return "";
    }

    private static List<String> j1 = new ArrayList<>();
    private static List<String> j2 = new ArrayList<>();

    public void setDrivewayNames() {
        if (j1.size() == 0) {
            j1.add("1");
            j1.add("2");
            j1.add("3");
            j1.add("4");
        }
        if (j2.size() == 0) {
            j2.add("5");
            j2.add("6");
            j2.add("7");
            j2.add("8");
        }
    }


    /**
     * 更换车位
     *
     * @param drivewayNames  车位号
     * @param trackId        股号
     * @param front          是否正向进入
     * @param tbLocomotiveVo 进入的车辆
     * @return
     */
    public String change(List<String> drivewayNames, String trackId, boolean front, TbLocomotiveVo tbLocomotiveVo) {
        //查询管理的车间信息
        List<TbParkingVo> tbParkingVos = tbParkingMapper.selectParkingListByTrackIdAndDrivewayNames(drivewayNames, trackId);
        int count = findLastZeroPosition2(tbParkingVos);
        if (count == 0) {
            return "已经停满了，停不下了";
        }
        //删掉原来停车信息
        TbParkingVo tbParkingVo1 = tbParkingMapper.selectByLmtNumber(tbLocomotiveVo.getLmtNumber());
        if (tbParkingVo1 != null) {
            TbParkingBo bo = new TbParkingBo();
            bo.setId(tbParkingVo1.getId());
            bo.setLmtNumber("");
            bo.setLmtType("");
            bo.setParkingNeed("");
            TbParkingBo bo1 = updateParking(bo);
            updateByBo(bo1);
        }
        tbParkingVos = tbParkingMapper.selectParkingListByTrackIdAndDrivewayNames(drivewayNames, trackId);
        //倒着进来的需要把list倒置
        if (!front) {
            Collections.reverse(tbParkingVos);
        }
        //判断最后一位是不是没有车号的
        if (StringUtils.isBlank(tbParkingVos.get(tbParkingVos.size() - 1).getLmtNumber())) {
            int lastZeroPosition = findLastZeroPosition(tbParkingVos);
            //没有车号往后排着
            TbParkingVo tbParkingVo = tbParkingVos.get(lastZeroPosition);
            TbParkingBo bo = new TbParkingBo();
            bo.setId(tbParkingVo.getId());
            bo.setLmtNumber(tbLocomotiveVo.getLmtNumber());
            bo.setLmtType(tbParkingVo.getLmtType());
            bo.setParkingNeed(tbLocomotiveVo.getLmtLength());
            TbParkingBo bo1 = updateParking(bo);
            updateByBo(bo1);
        } else {
            //最后一位没有车位的情况
            int lastZeroPosition3 = findLastZeroPosition3(tbParkingVos);
            List<TbParkingVo> tbParkingVos1 = tbParkingVos.subList(lastZeroPosition3, tbParkingVos.size());
            for (int i = 1; i < tbParkingVos1.size(); i++) {
                TbParkingBo bo = new TbParkingBo();
                bo.setId(tbParkingVos1.get(i - 1).getId());
                bo.setLmtNumber(tbParkingVos1.get(i).getLmtNumber());
                bo.setLmtType(tbParkingVos1.get(i).getLmtType());
                bo.setParkingNeed(tbParkingVos1.get(i).getParkingNeed());
                TbParkingBo bo1 = updateParking(bo);
                updateByBo(bo1);
            }
            TbParkingVo tbParkingVo = tbParkingVos1.get(tbParkingVos1.size() - 1);
            TbParkingBo bo = new TbParkingBo();
            bo.setId(tbParkingVo.getId());
            bo.setLmtNumber(tbLocomotiveVo.getLmtNumber());
            bo.setLmtType(tbLocomotiveVo.getLmtType());
            bo.setParkingNeed(tbLocomotiveVo.getLmtLength());
            TbParkingBo bo1 = updateParking(bo);
            updateByBo(bo1);
        }
        return "";
    }

    //拿去连续的尾部第一个空车位的位置
    public int findLastZeroPosition(List<TbParkingVo> list) {
        int idx = -1;
        for (int i = list.size() - 1; i >= 0; i--) {
            if (StringUtils.isBlank(list.get(i).getLmtNumber())) {
                idx = i;
            } else {
                break;
            }
        }
        return idx;
    }

    //获取空车数量
    public int findLastZeroPosition2(List<TbParkingVo> list) {
        int idx = list.size();
        for (TbParkingVo vo : list) {
            if (StringUtils.isNotBlank(vo.getLmtNumber())) {
                idx--;
            }
        }
        return idx;
    }

    //第一个最后一个空位置
    public int findLastZeroPosition3(List<TbParkingVo> list) {
        for (int i = list.size() - 1; i >= 0; i--) {
            if (StringUtils.isBlank(list.get(i).getLmtNumber())) {
                return i;
            }
        }
        return -1;
    }


}
